]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
js: Change main.pushModal to return the Clutter.Grab handle
authorCarlos Garnacho <carlosg@gnome.org>
Thu, 25 Nov 2021 09:49:42 +0000 (10:49 +0100)
committerCarlos Garnacho <carlosg@gnome.org>
Sat, 29 Jan 2022 00:16:30 +0000 (01:16 +0100)
All callers have been updated to keep this handle to identify their
own grab.

Also, optionally use the windowing state to determine whether
the grab is suitable for the specific uses. This removes the need
to trying to grab twice in the places where we settle for a keyboard
grab.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2045>

12 files changed:
js/gdm/loginDialog.js
js/ui/dnd.js
js/ui/grabHelper.js
js/ui/lookingGlass.js
js/ui/main.js
js/ui/modalDialog.js
js/ui/overview.js
js/ui/padOsd.js
js/ui/popupMenu.js
js/ui/screenShield.js
js/ui/switcherPopup.js
js/ui/unlockDialog.js

index 6c5018006ef1cafd6f8f4a9d83f991bd270632cf..3294d655663f23bf9f3ef0f94684635c50133e4e 100644 (file)
@@ -1289,7 +1289,7 @@ var LoginDialog = GObject.registerClass({
 
         this.opacity = 0;
 
-        Main.pushModal(global.stage, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
+        this._grab = Main.pushModal(global.stage, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
 
         this.ease({
             opacity: 255,
@@ -1301,7 +1301,8 @@ var LoginDialog = GObject.registerClass({
     }
 
     close() {
-        Main.popModal(global.stage);
+        Main.popModal(this._grab);
+        this._grab = null;
         Main.ctrlAltTabManager.removeGroup(this);
     }
 
index f6324f14e042d7b1b6f6501a76dc74224b3e7b0b..d6a1f07c827854d776c6f8bbb79d1780811d0f86 100644 (file)
@@ -117,7 +117,6 @@ var _Draggable = class _Draggable {
         this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
         this._dragCancellable = true;
 
-        this._eventsGrabbed = false;
         this._capturedEventId = 0;
     }
 
@@ -208,18 +207,22 @@ var _Draggable = class _Draggable {
     }
 
     _grabEvents(device, touchSequence) {
-        if (!this._eventsGrabbed) {
-            this._eventsGrabbed = Main.pushModal(_getEventHandlerActor());
-            if (this._eventsGrabbed)
+        if (!this._eventsGrab) {
+            let grab = Main.pushModal(_getEventHandlerActor());
+            if ((grab.get_seat_state() & Clutter.GrabState.POINTER) !== 0) {
                 this._grabDevice(_getEventHandlerActor(), device, touchSequence);
+                this._eventsGrab = grab;
+            } else {
+                Main.popModal(grab);
+            }
         }
     }
 
     _ungrabEvents() {
-        if (this._eventsGrabbed) {
+        if (this._eventsGrab) {
             this._ungrabDevice();
-            Main.popModal(_getEventHandlerActor());
-            this._eventsGrabbed = false;
+            Main.popModal(this._eventsGrab);
+            this._eventsGrab = null;
         }
     }
 
index 89e1bee3216f4fa1c29b7b1b37457efd8b899f34..47a332a246c8bb059fbefd9f1c995639f6eacf7d 100644 (file)
@@ -181,9 +181,13 @@ var GrabHelper = class GrabHelper {
     _takeModalGrab() {
         let firstGrab = this._modalCount == 0;
         if (firstGrab) {
-            if (!Main.pushModal(this._owner, this._modalParams))
+            let grab = Main.pushModal(this._owner, this._modalParams);
+            if (grab.get_seat_state() === Clutter.GrabState.NONE) {
+                Main.popModal(grab);
                 return false;
+            }
 
+            this._grab = grab;
             this._capturedEventId = this._owner.connect('captured-event',
                 (actor, event) => {
                     return this.onCapturedEvent(event);
@@ -202,7 +206,8 @@ var GrabHelper = class GrabHelper {
         this._owner.disconnect(this._capturedEventId);
         this._ignoreUntilRelease = false;
 
-        Main.popModal(this._owner);
+        Main.popModal(this._grab);
+        this._grab = null;
     }
 
     // ignoreRelease:
index 93d08f3fa8bed62e96ae6cf59535ff7a49d3bc2b..ed217a4dbb365f16dc766862a46169a0721940c2 100644 (file)
@@ -1560,9 +1560,13 @@ class LookingGlass extends St.BoxLayout {
         if (this._open)
             return;
 
-        if (!Main.pushModal(this, { actionMode: Shell.ActionMode.LOOKING_GLASS }))
+        let grab = Main.pushModal(this, { actionMode: Shell.ActionMode.LOOKING_GLASS });
+        if (grab.get_seat_state() === Clutter.GrabState.NONE) {
+            Main.popModal(grab);
             return;
+        }
 
+        this._grab = grab;
         this._notebook.selectIndex(0);
         this.show();
         this._open = true;
@@ -1602,7 +1606,8 @@ class LookingGlass extends St.BoxLayout {
             duration,
             mode: Clutter.AnimationMode.EASE_OUT_QUAD,
             onComplete: () => {
-                Main.popModal(this);
+                Main.popModal(this._grab);
+                this._grab = null;
                 this.hide();
             },
         });
index 11ac073bbe5b10854826eef56c81861294afdab5..14a541f0a62f7dee04a935c3b82d3bbc04a5e1c4 100644 (file)
@@ -503,9 +503,9 @@ function notifyError(msg, details) {
     notify(msg, details);
 }
 
-function _findModal(actor) {
+function _findModal(grab) {
     for (let i = 0; i < modalActorFocusStack.length; i++) {
-        if (modalActorFocusStack[i].actor == actor)
+        if (modalActorFocusStack[i].grab === grab)
             return i;
     }
     return -1;
@@ -537,7 +537,7 @@ function _findModal(actor) {
  *                global keybindings; the default of NONE will filter
  *                out all keybindings
  *
- * @returns {bool}: true iff we successfully acquired a grab or already had one
+ * @returns {Clutter.Grab}: the grab handle created
  */
 function pushModal(actor, params) {
     params = Params.parse(params, { timestamp: global.get_current_time(),
@@ -551,9 +551,9 @@ function pushModal(actor, params) {
 
     modalCount += 1;
     let actorDestroyId = actor.connect('destroy', () => {
-        let index = _findModal(actor);
+        let index = _findModal(grab);
         if (index >= 0)
-            popModal(actor);
+            popModal(grab);
     });
 
     let prevFocus = global.stage.get_key_focus();
@@ -577,14 +577,13 @@ function pushModal(actor, params) {
 
     actionMode = params.actionMode;
     global.stage.set_key_focus(actor);
-    return true;
+    return grab;
 }
 
 /**
  * popModal:
- * @param {Clutter.Actor} actor: the actor passed to original invocation
- *     of pushModal()
- * @param {number=} timestamp: optional timestamp
+ * @param {Clutter.Grab} grab - the grab given by pushModal()
+ * @param {number=} timestamp - optional timestamp
  *
  * Reverse the effect of pushModal(). If this invocation is undoing
  * the topmost invocation, then the focus will be restored to the
@@ -594,11 +593,11 @@ function pushModal(actor, params) {
  * initiated event. If not provided then the value of
  * global.get_current_time() is assumed.
  */
-function popModal(actor, timestamp) {
+function popModal(grab, timestamp) {
     if (timestamp == undefined)
         timestamp = global.get_current_time();
 
-    let focusIndex = _findModal(actor);
+    let focusIndex = _findModal(grab);
     if (focusIndex < 0) {
         global.stage.set_key_focus(null);
         actionMode = Shell.ActionMode.NORMAL;
@@ -611,8 +610,7 @@ function popModal(actor, timestamp) {
     let record = modalActorFocusStack[focusIndex];
     record.actor.disconnect(record.destroyId);
 
-    let grab = record.grab;
-    grab.dismiss();
+    record.grab.dismiss();
 
     if (focusIndex == modalActorFocusStack.length - 1) {
         if (record.prevFocus)
index 4b3078ae5e4e015b3efa817ef7dc31e70940a83c..259a9c6bbc5055ba39d9cb7399334e9c5aa14ec3 100644 (file)
@@ -204,7 +204,8 @@ var ModalDialog = GObject.registerClass({
             this._savedKeyFocus = focus;
         else
             this._savedKeyFocus = null;
-        Main.popModal(this, timestamp);
+        Main.popModal(this._grab, timestamp);
+        this._grab = null;
         this._hasModal = false;
 
         if (!this._shellReactive)
@@ -218,9 +219,13 @@ var ModalDialog = GObject.registerClass({
         let params = { actionMode: this._actionMode };
         if (timestamp)
             params['timestamp'] = timestamp;
-        if (!Main.pushModal(this, params))
+        let grab = Main.pushModal(this, params);
+        if (grab.get_seat_state() === Clutter.GrabState.NONE) {
+            Main.popModal(grab);
             return false;
+        }
 
+        this._grab = grab;
         Main.layoutManager.emit('system-modal-opened');
 
         this._hasModal = true;
index bcfdca3442c79faff7564a828aca299824661c03..2a603ba02f809d6b77ccd3182100d783ec154272 100644 (file)
@@ -492,9 +492,12 @@ var Overview = class {
             let shouldBeModal = !this._inXdndDrag;
             if (shouldBeModal && !this._modal) {
                 let actionMode = Shell.ActionMode.OVERVIEW;
-                if (Main.pushModal(global.stage, { actionMode })) {
+                let grab = Main.pushModal(global.stage, { actionMode });
+                if (grab.get_seat_state() !== Clutter.GrabState.NONE) {
+                    this._grab = grab;
                     this._modal = true;
                 } else {
+                    Main.popModal(grab);
                     this.hide();
                     return false;
                 }
@@ -502,7 +505,8 @@ var Overview = class {
         } else {
             // eslint-disable-next-line no-lonely-if
             if (this._modal) {
-                Main.popModal(global.stage);
+                Main.popModal(this._grab);
+                this._grab = false;
                 this._modal = false;
             }
         }
index 9de5b49276161cefcc00bb32e626e5dcc57b05cb..8362b101d57b892f0701e0b19be4ea4851675eab 100644 (file)
@@ -723,7 +723,7 @@ var PadOsd = GObject.registerClass({
         buttonBox.add_actor(this._editButton);
 
         this._syncEditionMode();
-        Main.pushModal(this);
+        this._grab = Main.pushModal(this);
     }
 
     _updatePadChooser() {
@@ -919,7 +919,8 @@ var PadOsd = GObject.registerClass({
     }
 
     _onDestroy() {
-        Main.popModal(this);
+        Main.popModal(this._grab);
+        this._grab = null;
         this._actionEditor.close();
 
         let seat = Clutter.get_default_backend().get_default_seat();
index 3a0e53c911bc0a698219e04a4df347588caa95b5..a0c00067d1eb7f7bcd8f0b25c5ed9cdb449ce6bc 100644 (file)
@@ -1329,8 +1329,10 @@ var PopupMenuManager = class {
     }
 
     removeMenu(menu) {
-        if (menu == this.activeMenu)
-            Main.popModal(menu.actor);
+        if (menu === this.activeMenu) {
+            Main.popModal(this._grab);
+            this._grab = null;
+        }
 
         let position = this._findMenu(menu);
         if (position == -1) // not a menu we manage
@@ -1353,12 +1355,13 @@ var PopupMenuManager = class {
         if (open) {
             if (this.activeMenu)
                 this.activeMenu.close(BoxPointer.PopupAnimation.FADE);
-            Main.pushModal(menu.actor, this._grabParams);
+            this._grab = Main.pushModal(menu.actor, this._grabParams);
             this.activeMenu = menu;
         } else {
             if (this.activeMenu === menu)
                 this.activeMenu = null;
-            Main.popModal(menu.actor);
+            Main.popModal(this._grab);
+            this._grab = null;
         }
     }
 
index f18314b6494f14d55b51218050bac728d1f2af4c..3d1a6eb1adacf80f433125cac8a7de582c7df03a 100644 (file)
@@ -192,14 +192,15 @@ var ScreenShield = class {
         if (this._isModal)
             return true;
 
-        this._isModal = Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOCK_SCREEN });
+        let grab = Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOCK_SCREEN });
+
+        // We expect at least a keyboard grab here
+        this._isModal = (grab.get_seat_state() & Clutter.GrabState.KEYBOARD) !== 0;
         if (this._isModal)
-            return true;
+            this._grab = grab;
+        else
+            Main.popModal(grab);
 
-        // We failed to get a pointer grab, it means that
-        // something else has it. Try with a keyboard grab only
-        this._isModal = Main.pushModal(this.actor, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED,
-                                                     actionMode: Shell.ActionMode.LOCK_SCREEN });
         return this._isModal;
     }
 
@@ -550,7 +551,8 @@ var ScreenShield = class {
             this._dialog.popModal();
 
         if (this._isModal) {
-            Main.popModal(this.actor);
+            Main.popModal(this._grab);
+            this._grab = null;
             this._isModal = false;
         }
 
index ccc8b0fb0eb293f152c77a5f9328f8f11dfa66d6..17c3fcaa3e293fa9875ca88cb6530bdc1e09a39a 100644 (file)
@@ -1,7 +1,7 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 /* exported SwitcherPopup, SwitcherList */
 
-const { Clutter, GLib, GObject, Meta, St } = imports.gi;
+const { Clutter, GLib, GObject, St } = imports.gi;
 
 const Main = imports.ui.main;
 
@@ -100,11 +100,13 @@ var SwitcherPopup = GObject.registerClass({
         if (this._items.length == 0)
             return false;
 
-        if (!Main.pushModal(this)) {
-            // Probably someone else has a pointer grab, try again with keyboard only
-            if (!Main.pushModal(this, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED }))
-                return false;
+        let grab = Main.pushModal(this);
+        // We expect at least a keyboard grab here
+        if ((grab.get_seat_state() & Clutter.GrabState.KEYBOARD) === 0) {
+            Main.popModal(grab);
+            return false;
         }
+        this._grab = grab;
         this._haveModal = true;
         this._modifierMask = primaryModifier(mask);
 
@@ -306,7 +308,8 @@ var SwitcherPopup = GObject.registerClass({
 
     _popModal() {
         if (this._haveModal) {
-            Main.popModal(this);
+            Main.popModal(this._grab);
+            this._grab = null;
             this._haveModal = false;
         }
     }
index b33da66a1fb549895d23b61e244be7a225d2154f..7fa307aa9230413622ab010f9f37b073f5bcf4db 100644 (file)
@@ -904,9 +904,13 @@ var UnlockDialog = GObject.registerClass({
             timestamp,
             actionMode: Shell.ActionMode.UNLOCK_SCREEN,
         };
-        if (!Main.pushModal(this, modalParams))
+        let grab = Main.pushModal(this, modalParams);
+        if (grab.get_seat_state() !== Clutter.GrabState.ALL) {
+            Main.popModal(grab);
             return false;
+        }
 
+        this._grab = grab;
         this._isModal = true;
 
         return true;
@@ -918,7 +922,8 @@ var UnlockDialog = GObject.registerClass({
 
     popModal(timestamp) {
         if (this._isModal) {
-            Main.popModal(this, timestamp);
+            Main.popModal(this._grab, timestamp);
+            this._grab = null;
             this._isModal = false;
         }
     }